#include "BirthClinic/include/Agents/BCAgent.h"
#include "BirthClinic/include/BCSharedData.h"
#include "Coord2d.h"

int RenderTextToSurface(std::string Text, int x, int y, SDL_Surface *Dest);

BCAgent::BCAgent(World *__world, bool mainAgent_) :
		RobotAgent(__world) {
	_maxAge = -1;
	_currentAge = 0;
	_infancy = -2;
	_state = KID;
	_postnatalCounter = 0;
	_constructionPeriod = BCSharedData::_constructionPeriod;


	_wm->_agentId = BCSharedData::_robotId;
	BCSharedData::_robotId++;

	_mainAgent = mainAgent_;
	if (_mainAgent) {

		_maxAge =
				rand()
						% (BCSharedData::_organismMaxLife
								- BCSharedData::_organismMinLife)
						+ BCSharedData::_organismMinLife;

		_infancy = BCSharedData::_organismInfancyDuration;

		this->setAgentMask(BCSharedData::_gMainAgentMaskImage);

		//this->_wm->_agentAbsoluteOrientation =-120;
	} else {
		this->_genotype = NULL;
		this->setAgentMask(BCSharedData::_gComponentAgentMaskImage);
		this->_wm->_agentAbsoluteOrientation = -90;
	}

	unregisterAgent();
}

BCAgent::~BCAgent() {
}

void BCAgent::buildGenotype() {
	if (_mainAgent) {
		Coord2d myCoords = getPosition();
		this->_genotype = new BCGenotype((BCAgentWorldModel*) this->_wm,
				myCoords);
	}
}

void BCAgent::buildGenotype(BCGenotype* parent1_, BCGenotype* parent2_) {
	if (_mainAgent) {
		Coord2d myCoords = this->getPosition();
		_genotype = new BCGenotype((BCAgentWorldModel*) this->_wm, parent1_,
				parent2_, myCoords);
	}
}

BCAgentWorldModel* BCAgent::getWorldModel() {
	return dynamic_cast<BCAgentWorldModel*>(_wm);
}

BCGenotype* BCAgent::getGenotype() {
	return _genotype;
}

void BCAgent::stepBehavior() {
	// update status
	_iterations++;
	_behavior->step();
	displayInfo();
}

int BCAgent::genotypeSize() {
	return this->_genotype->getSize();
}

void BCAgent::initiateOrganism() {
	this->setOrganism(new Organism());
	this->getOrganism()->addRobot(shared_from_this());
	this->registerAgent();
	Organism::add(this->getOrganism());
}

Coord2d BCAgent::getShift(int index_) {
	return this->_genotype->getCoordOfGene(index_);
}

BCGene BCAgent::getGene(int index_) {
	return this->_genotype->getGene(index_);
}

Coord2d BCAgent::getPosition() {
	Coord2d coord;
	coord._x = this->_wm->getPosition().x;
	coord._y = this->_wm->getPosition().y;
	return coord;
}

bool BCAgent::isMainAgent() {
	return _mainAgent;
}

void BCAgent::printInfo() {
	if (_mainAgent)
		_genotype->printGenotypeInfo();
}

void BCAgent::increaseAge() {

	if( _constructionPeriod == 0){
		_currentAge++;

		if (_currentAge == _infancy) {
			_state = ADULT;
		} else if (_currentAge == _maxAge) {
			_state = DEAD;
		}

		if(_postnatalCounter>0){
			_postnatalCounter--;
		}
	}
	else{
		_constructionPeriod--;
	}

}

int BCAgent::getAge() {
	return _currentAge;
}

int BCAgent::getId() {
	return _wm->_agentId;
}

LifeCycleState BCAgent::getState() {
	return _state;
}

void BCAgent::addComponent(int compId_){
	_components.push_back(compId_);
}

std::vector<int> BCAgent::getComponents(){
	return _components;
}

int BCAgent::getSensorValue(int sensorId_){
	return _wm->getDefaultSensors()->getSensorDistanceValue(sensorId_);
}

void BCAgent::startCooldownPeriod(){
	_postnatalCounter = BCSharedData::_postnatalPeriod;
}

bool BCAgent::canReproduce(){
	return (_postnatalCounter == 0 );
}

int BCAgent::getConstructionPeriod(){
	return _constructionPeriod;
}

int BCAgent::evaluate(){
	return _genotype->getSize();
}

int BCAgent::getSize(){
	if(_constructionPeriod==0)
		return _genotype->getSize();

	return -1;
}
